package com.dream.auth.config;


import com.dream.auth.config.security.service.ClientDetailsServiceImpl;
import com.dream.auth.config.security.service.UserDetailsServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;

import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.List;


@Slf4j
@Configuration
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    private final static Logger logger = LoggerFactory.getLogger(AuthorizationServerConfig.class);
    @Autowired
    private ClientDetailsServiceImpl clientDetailsService;
    @Autowired
    private DataSource dataSource;
    //@Autowired
    //@Qualifier("redisTokenStore")
    private TokenStore redisTokenStore;
    @Autowired
    UserDetailsServiceImpl userDetailsService;
    @Autowired
    @Qualifier("jwtTokenStore")
    private TokenStore jwtTokenStore;
    @Autowired
    private JwtAccessTokenConverter jwtAccessTokenConverter;
    @Autowired
    private TokenEnhancer jwtTokenEnhancer;

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
     @Override
     public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
         clients.withClientDetails(clientDetailsService);
        /* clients.inMemory()
                 //配置client-id
                 .withClient("dream-kgBuilder")
                 //配置client-secret
                 .secret(bCryptPasswordEncoder.encode("dream-kgBuilder_secret"))
                 //配置访问token的有效期
                 // .accessTokenValiditySeconds(3600)
                 //配置redirect_uri,用于授权成功后跳转
                 .redirectUris("https://www.baidu.com")
                 //配置申请的权限范围
                 .scopes("all")
                 //配置grant_type，表示授权类型
                 .authorizedGrantTypes("password","refresh_token","authorization_code");*/
     }
    /*@Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.jdbc(dataSource);
       //JdbcClientDetailsService jdbcClientDetailsService = new JdbcClientDetailsService(dataSource);
        // clients.withClientDetails(jdbcClientDetailsService);
    }*/

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.pathMapping("/oauth/confirm_access","/oauth2/confirm_access");
        //配置JWT内容增强器
        TokenEnhancerChain enhancerChain = new TokenEnhancerChain();
        List<TokenEnhancer> delegates = new ArrayList<>();
        delegates.add(jwtTokenEnhancer);
        delegates.add(jwtAccessTokenConverter);
        enhancerChain.setTokenEnhancers(delegates);
        endpoints.userDetailsService(userDetailsService)
                .authenticationManager(authenticationManager)
                .tokenStore(jwtTokenStore)
                .accessTokenConverter(jwtAccessTokenConverter).tokenEnhancer(enhancerChain);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        //允许客户端访问 OAuth2 授权接口，否则请求 token 会返回 401。
        security.allowFormAuthenticationForClients();
        //允许已授权用户获取 token 接口。
        security.tokenKeyAccess("isAuthenticated()");
        //允许已授权用户访问 checkToken 接口
        security.checkTokenAccess("isAuthenticated()");
    }
}
